local deck = {}
local hand = {}
local hold = {}

local function init()
	for i = 1,13*4 do
		deck[i] = i
	end
	hand = {}
	hold = {false,false,false,false,false}
end

--Interaction functions--
local function getCard(pos)
	local ret = table.remove(deck,math.random(#deck))
	if pos then
		table.insert(deck,hand[pos])
		hand[pos] = ret
	end
	return ret
end

local function getDeck()
	for i = 1,5 do
		if not hold[i] then
			if hand[i] then table.insert(deck,hand[i]) end
			hand[i] = getCard()
		end
	end
	return hand
end

local function editHold(args)
	if args == nil then return hold end
	for i,v in ipairs(args) do
		if v > 0 and v < 6 then
			hold[v] = not hold[v]
		end
	end
	return hold
end

--Win calculation logic functions--
local function flushCheck(cards)
	local suit = cards[1][2]
	for k,v in ipairs(cards) do
		if suit ~= v[2] then return false end
	end
	return true
end
local function straightCheck(cards)
	for i = 1,4 do
		if cards[i][1] ~= cards[i+1][1]+1 then return false end
	end
	return true
end
local function royalFlushCheck(cards)
	if not flushCheck(cards) then return false end

	local check = {1,10,11,12,13}
	for k,v in ipairs(cards) do
		if v[1] ~= check[k] then return false end
	end
	return true
end
local function straightFlushCheck(cards)
	if not flushCheck(cards) then return false end
	return straightCheck(cards)
end
local function fourOfAKindCheck(count)
	if count[4] then return true end
	return false
end
local function fullHouseCheck(count)
	if count[3] and count[2] then return true end
	return false
end
local function threeOfAKindCheck(count)
	if count[3] then return true end
	return false
end
local function twoPairCheck(count)
	if not count[2] then return false end
	if count[2] > 13 then return true end
	return false
end
local function jacksPairCheck(cards,count)
	if not count[2] then return false end
	if count[2] < 11 and count[2] ~= 1 then return false end
	return true
end
local function calculateWin()
	local cards = {}
	for k,v in ipairs(hand) do
		cards[k] = {}
		cards[k][1] = (v-1)%13+1
		cards[k][2] = (v-1)//13+1
	end
	table.sort(cards,function(a,b)
		return a[1]<b[1]
	end)
	local total = {}
	for k,v in ipairs(cards) do
		if not total[v[1]] then total[v[1]] = 1
		else total[v[1]] = total[v[1]] + 1 end
	end
	local count = {}
	for k,v in pairs(total) do
		if not count[v] then count[v] = k
		else count[v] = count[v] + 13 end
	end

	if royalFlushCheck(cards) then return 800
	elseif straightFlushCheck(cards) then return 50
	elseif fourOfAKindCheck(count) then return 25
	elseif fullHouseCheck(count) then return 9
	elseif flushCheck(cards) then return 6
	elseif straightCheck(cards) then return 4
	elseif threeOfAKindCheck(count) then return 3
	elseif twoPairCheck(count) then return 2
	elseif jacksPairCheck(cards,count) then return 1
	else return 0
	end
end

return {
	init = init,	
	deck = getDeck,
	card = getCard,
	hand = function() return hand end,
	hold = editHold,
	calc = calculateWin
}
